package com.tencreat.mall.controller.admin;

import cn.hutool.extra.cglib.CglibUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tencreat.common.annotation.Log;
import com.tencreat.common.convert.ExcelBigNumberConvert;
import com.tencreat.common.core.HttpResult;
import com.tencreat.common.core.controller.BaseController;
import com.tencreat.common.core.domain.AjaxResult;
import com.tencreat.common.core.domain.model.ReqIdParam;
import com.tencreat.common.core.domain.model.ReqIdsParam;
import com.tencreat.common.enums.BusinessType;
import com.tencreat.common.enums.OrderStatus;
import com.tencreat.common.utils.LogisticsUtils;
import com.tencreat.common.utils.poi.ExcelNewUtil;
import com.tencreat.common.utils.poi.ExcelUtil;
import com.tencreat.domain.account.MallStore;
import com.tencreat.domain.account.MallUser;
import com.tencreat.domain.mall.MallOrder;
import com.tencreat.domain.mall.MallOrderGoods;
import com.tencreat.domain.mall.MallSelfmentionOrder;
import com.tencreat.domain.mall.dto.MallOrderShipDTO;
import com.tencreat.domain.mall.dto.MallUserAndOrderTimeDTO;
import com.tencreat.domain.mall.vo.*;
import com.tencreat.service.account.IMallStoreService;
import com.tencreat.service.mall.IMallOrderGoodsService;
import com.tencreat.service.mall.IMallOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 总管理订单Controller
 *
 * @author tencreat
 * @date 2021-08-15
 */
@Api(tags = "订单api")
@RestController
@RequestMapping("/mall/order")
public class AdminMallOrderController extends BaseController {
    @Autowired
    private IMallOrderService mallOrderService;

    @Autowired
    private IMallOrderGoodsService mallOrderGoodsService;

    @Autowired
    private IMallStoreService mallStoreService;


    /**
     * 查询订单列表
     */
    @ApiOperation(value = "查询订单列表")
    @PreAuthorize("@ss.hasPermi('mall:order:list')")
    @PostMapping("/list")
    public HttpResult<IPage<MallOrder>> list(@RequestBody MallOrder mallOrder) {
        Page<MallOrder> page = new Page<>(mallOrder.getPageNum(), mallOrder.getPageSize());
        return HttpResult.ok(mallOrderService.page(page, mallOrder));
    }

    @ApiOperation(value = "查询充值记录列表")
    @PreAuthorize("@ss.hasPermi('mall:order:list')")
    @PostMapping("/rechargeList")
    public HttpResult<IPage<MallOrder>> rechargeList(@RequestBody MallOrder mallOrder) {
        Page<MallOrder> page = new Page<>(mallOrder.getPageNum(), mallOrder.getPageSize());
        return HttpResult.ok(mallOrderService.rechargeList(page, mallOrder));
    }

    /**
     * 导出订单列表
     */
    @ApiOperation(value = "导出订单列表")
    @PreAuthorize("@ss.hasPermi('mall:order:export')")
    @Log(title = "订单管理>订单管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(@RequestBody MallOrder mallOrder, HttpServletResponse response) {
        Page<MallOrder> page = new Page<>(1, Integer.MAX_VALUE);
        Page<MallOrder> page1 = mallOrderService.page(page, mallOrder);
        page1.getRecords().forEach(item -> {
            item.setCreateTime2(item.getCreateTime());
        });
        if (mallOrder.getType() == 0) {
            ExcelNewUtil.exportExcel(page1.getRecords(), "订单列表", MallOrder.class, response);
        }
        if (mallOrder.getType() == 1) {
            List<MallOrderVO2> list = CglibUtil.copyList(page1.getRecords(), MallOrderVO2::new);
            ExcelNewUtil.exportExcel(list, "订单发货", MallOrderVO2.class, response);
        }
        if (mallOrder.getType() == 2) {
            List<MallOrderVO3> list = CglibUtil.copyList(page1.getRecords(), MallOrderVO3::new);
            ExcelNewUtil.exportExcel(list, "订单自提", MallOrderVO3.class, response);
        }
        if (mallOrder.getType() == 3) {
            List<MallOrderVO4> list = CglibUtil.copyList(page1.getRecords(), MallOrderVO4::new);
            ExcelNewUtil.exportExcel(list, "虚拟订单", MallOrderVO4.class, response);
        }
        /*if (mallOrder.getType() == 4){
            List<MallOrderVO5> list = CglibUtil.copyList(page1.getRecords(), MallOrderVO5::new);
            ExcelNewUtil.exportExcel(list,"会员订单",MallOrderVO5.class, response);
        }*/
    }

    /**
     * 获取订单详细信息
     */
    @ApiOperation(value = "获取订单详细信息")
    @PreAuthorize("@ss.hasAnyPermi('mall:order:query,mall:supplier-order:deliver,mall:store-order:check')")
    @PostMapping(value = "/getInfo")
    public HttpResult<ResOrderDetailInfoVO> getInfo(@RequestBody ReqIdParam id) {
        return HttpResult.ok(mallOrderService.getOrderDetail(id));
    }

    /**
     * 订单数
     */
    @ApiOperation(value = "获取订单数")
    @PreAuthorize("@ss.hasPermi('mall:order:query')")
    @PostMapping(value = "/getInfoNum")
    public HttpResult<MallOrderStatisticsVO> getInfoNum(@RequestBody MallOrder mallOrder) {
        return mallOrderService.getInfoNum(mallOrder);
    }


    /**
     * 每日订单数
     */
    @ApiOperation(value = "每日订单数")
    @PreAuthorize("@ss.hasPermi('mall:order:query')")
    @PostMapping("/getOrderNum")
    public HttpResult<String> getNum(@RequestBody MallOrder mallOrder) throws ParseException {
        return mallOrderService.selectOrderNum(mallOrder);
    }

    /**
     * 每日订单收入折线图
     */
    @ApiOperation(value = " 每日订单收入折线图")
    @PostMapping("/getOrderIncomeDaily")
    public HttpResult<List<Map<String, Object>>> getOrderIncomeDaily(@RequestBody MallOrder params) {
        return mallOrderService.getOrderIncomeDaily(params);
    }

    /**
     * 现以改为三个折线图共用一个接口
     */
    @ApiOperation(value = " 首页折线图")
    @PostMapping("/getOrderNumDaily")
    public HttpResult<List<Map<String, Object>>> getOrderNumDaily(@RequestBody MallUserAndOrderTimeDTO dto) {
        return mallOrderService.getOrderNumDaily(dto);
    }

    /**
     * 每日新增用户折线图
     */
    @ApiOperation(value = " 每日新增用户折线图")
    @PostMapping("/addUserNumDaily")
    public HttpResult<List<Map<String, Object>>> getUserNumDaily(@RequestBody MallUser params) {
        return mallOrderService.getUserNumDaily(params);
    }

    /**
     * 订单详情
     */
    @ApiOperation(value = "订单详情")
    @PreAuthorize("@ss.hasPermi('mall:order:query')")
    @PostMapping("/getOrderDetails")
    public HttpResult<MallOrderVO> getOrderDetails(@RequestBody ReqIdParam idParam) {
        return mallOrderService.selectOrderDetailsById(idParam);
    }

    /**
     * 订单发货
     */
    @ApiOperation(value = "订单发货")
    @PreAuthorize("@ss.hasAnyPermi('mall:order:query,mall:supplier-order:deliver')")
    @Log(title = "订单管理>订单管理", businessType = BusinessType.UPDATE)
    @PostMapping("/ship")
    public HttpResult<Boolean> ship(@RequestBody MallOrderShipDTO mallOrderShipPO) {
        return mallOrderService.ship(mallOrderShipPO);
    }

    /**
     * 订单数
     */
    @ApiOperation(value = "获取订单数")
    @PostMapping(value = "/getIndexNum")
    public HttpResult<MallOrderStatisticsVO> getInfo(@RequestBody MallOrder mallOrder) {
        return mallOrderService.getInfo(mallOrder);
    }

    @ApiOperation(value = "最新订单")
    @PostMapping("/newOrder")
    public HttpResult<List<MallNewOrderVO>> getNewGoods(@RequestBody MallOrder mallOrder) {
        return mallOrderService.selectNewOrders(mallOrder);
    }

    @ApiOperation(value = "查看物流")
    @GetMapping("/checkLogistics")
    public HttpResult<?> checkLogistics(@ApiParam("快递单号") @RequestParam String no) {
        return LogisticsUtils.checkLogistics(no);
    }


    @ApiOperation(value = "首页统计饼图")
    @GetMapping("/indexStatistics")
    public HttpResult<AdminIndexStaticsVO> indexStatistics() {
        return HttpResult.ok(mallOrderService.indexStatistics());
    }

    @ApiOperation(value = "订单管理数据统计")
    //@GetMapping("/orderStatistics")
    public HttpResult<MallAdminOrderStatisticsVO> orderStatistics(@ApiParam("订单标记 4-虚拟订单,1-自提") @RequestParam(required = false) Integer orderMold) {
        return HttpResult.ok(mallOrderService.orderStatistics(null, orderMold));
    }

    @ApiOperation(value = "订单管理数据统计1")
    @PostMapping("/orderStatistics1")
    public HttpResult<MallAdminOrderStatisticsVO> orderStatistics1(@RequestBody ReqIdParam idParam) {

        return HttpResult.ok(mallOrderService.orderStatistics1(null, idParam));
    }


    @ApiOperation(value = "核销")
    @PreAuthorize("@ss.hasAnyPermi('mall:order:query,mall:store-order:check')")
    @PostMapping("/check")
    public HttpResult<Boolean> check(@RequestBody MallOrder mallOrder) {
        Long userId = getLoginCheck().getUser().getUserId();
        MallStore mallStore = mallStoreService.lambdaQuery().eq(MallStore::getUserId, userId).one();
        if (mallStore != null) {
            mallOrder.setStoreId(mallStore.getId());
        }
        mallOrder.setUserId(userId);
        return mallOrderService.check(mallOrder);
    }

    @ApiOperation(value = "充值订单管理数据统计")
    @PostMapping("/rechargeOrderStatistics")
    public HttpResult<MallAdminOrderStatisticsVO> rechargeOrderStatistics(@RequestBody ReqIdParam idParam) {
        return HttpResult.ok(mallOrderService.rechargeOrderStatistics(null, idParam));
    }


    @ApiOperation(value = "导出有买有卖财务统计表")
    @PostMapping("/exportTotal")
    public void exportTotal(HttpServletResponse response) throws IOException {
        TotalOrderStatisticsVO totalOrderStatisticsVO = mallOrderService.exportOrderStatisticsVO();


        // 创建工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
//        设置样式
        HSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) 10.5);
        font.setFontName("宋体");
        font.setColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
//        font.setBold(true);
        HSSFCellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);//居中
        style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
//        style.setFillForegroundColor(HSSFColor.HSSFColorPredefined.LIGHT_TURQUOISE.getIndex());//背景颜色
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);//设置实心
        style.setBorderBottom(BorderStyle.THIN);//下边框
        style.setBorderLeft(BorderStyle.THIN);//左边框
        style.setBorderTop(BorderStyle.THIN);//上边框
        style.setBorderRight(BorderStyle.THIN);//有边框
        style.setFont(font);

        // 创建工作表
        HSSFSheet sheet = workbook.createSheet("有买有卖财务管理");

        String sheetName = "有买有卖财务管理";

        //行号
        int iRow = 0;

        //最大列数
        int iMaxCol = 7;

        for (int i = 0; i <= iMaxCol; i++) {
            //设置单元格宽度和高度
            sheet.setColumnWidth(i, 256 * 12);  //设置第1列的宽度为13个字符（256是一个字符的宽度）
            //row.setHeightInPoints(30);  //设置行高为30个点
        }
        for (int i = 1; i <= 17; i++) {
            if (i >= 3 && i < 8 || i >= 10 && i < 15) {
                continue;
            }
            // 创建表头行 合并所有行列
            HSSFRow headerRow = sheet.createRow(i - 1);

            //设置行高
            headerRow.setHeightInPoints(25);

            // 合并单元格的内容，合并单元格后，仅会保留第一行，第八列的内容，所以设置第一行第八列的内容
            Cell cell0 = headerRow.createCell(0);
            cell0.setCellStyle(style);
            if (i == 1) {
                cell0.setCellValue("有买有卖财务管理");
            }
            if (i == 2) {
                cell0.setCellValue("统计明细");
            }
            if (i == 9) {
                cell0.setCellValue("充值金额分账（现金）");
            }
            if (i == 15) {
                cell0.setCellValue("说明：便于对接支付系统");
            }
            if (i == 17) {
                cell0.setCellValue("账户核对");
            }
            CellRangeAddress region = new CellRangeAddress(i - 1, i - 1, 0, iMaxCol);
            sheet.addMergedRegion(region);
            //给合并单元格加边框
            setRegionBorder(region, sheet);
        }

        //合并3、4、5、6、7、10、11、12、13、14行的第1、2列
        for (int i = 3; i <= 14; i++) {
            if (i == 8 || i == 9) {
                continue;
            }
            HSSFRow threeRow = sheet.createRow(i - 1);

            //设置行高
            threeRow.setHeightInPoints(25);

            Cell cell2 = threeRow.createCell(0);
            cell2.setCellStyle(style);

            Cell cell3 = threeRow.createCell(2);
            cell3.setCellStyle(style);

            if (i == 3) {
                cell2.setCellValue("代采购充值统计明细");
                cell3.setCellValue(String.valueOf(totalOrderStatisticsVO.getRechargeAmount()));
            }
            if (i == 4) {
                cell2.setCellValue("实体店消费券核销统计");
                cell3.setCellValue(String.valueOf(totalOrderStatisticsVO.getStoreConsumeRoll()));
            }
            if (i == 5) {
                cell2.setCellValue("API对接门店消费券核销统计");
                cell3.setCellValue("0");
            }
            if (i == 6) {
                cell2.setCellValue("自营商城消费券核销统计");
                cell3.setCellValue(String.valueOf(totalOrderStatisticsVO.getShopConsumeRoll()));
            }
            if (i == 7) {
                cell2.setCellValue("未核销消费券统计明细");
                cell3.setCellValue(String.valueOf(totalOrderStatisticsVO.getWaitConsumeRoll()));
            }
            if (i == 10) {
                cell2.setCellValue("消费券核销账户");
                cell3.setCellValue(String.valueOf(totalOrderStatisticsVO.getVerificationConsumeRoll()));
            }
            if (i == 11) {
                cell2.setCellValue("提货单核销账户");
                cell3.setCellValue(String.valueOf(totalOrderStatisticsVO.getVerificationGoodsRoll()));
            }
            if (i == 12) {
                cell2.setCellValue("公司管理费收益账户");
                cell3.setCellValue(String.valueOf(totalOrderStatisticsVO.getManagement()));
            }
            if (i == 13) {
                cell2.setCellValue("保证金账户");
                cell3.setCellValue(String.valueOf(totalOrderStatisticsVO.getEarnestMoney()));
            }
            if (i == 14) {
                cell2.setCellValue("运营账户");
                cell3.setCellValue(String.valueOf(totalOrderStatisticsVO.getOperator()));
            }
            //合并一二列
            CellRangeAddress region3 = new CellRangeAddress(i - 1, i - 1, 0, 1);
            sheet.addMergedRegion(region3);
            setRegionBorder(region3, sheet);

            //合并三四列
            CellRangeAddress region4 = new CellRangeAddress(i - 1, i - 1, 2, iMaxCol);
            sheet.addMergedRegion(region4);
            setRegionBorder(region4, sheet);
        }


        for (int i = 18; i <= 25; i++) {

            HSSFRow nineteenRow = sheet.createRow(i - 1);

            //设置行高
            nineteenRow.setHeightInPoints(25);

            if (i == 18 || i == 23 || i == 24) {
                Cell cell18 = nineteenRow.createCell(2);
                cell18.setCellStyle(style);
                if (i == 18) {
                    Cell cell19 = nineteenRow.createCell(0);
                    cell19.setCellStyle(style);
                    cell19.setCellValue("消费券核销账户");
                    CellRangeAddress region20 = new CellRangeAddress(17, 20, 0, 1);
                    sheet.addMergedRegion(region20);
                    setRegionBorder(region20, sheet);
                    cell18.setCellValue(String.valueOf(totalOrderStatisticsVO.getUseTotalConsumeRoll()) + "=" + String.valueOf(totalOrderStatisticsVO.getUseConsumeRoll()));

                }
                if (i == 23) {
                    cell18.setCellValue(String.valueOf(totalOrderStatisticsVO.getPresentsGoodsRoll())+ "=" + String.valueOf(totalOrderStatisticsVO.getPresentsGoodsRoll()));
                }
                if (i == 24) {
                    cell18.setCellValue(String.valueOf(totalOrderStatisticsVO.getWaitGoodsRoll())+ "=" + String.valueOf(totalOrderStatisticsVO.getWaitGoodsRoll()));
                }
                CellRangeAddress region21 = new CellRangeAddress(i - 1, i - 1, 2, iMaxCol);
                sheet.addMergedRegion(region21);
                setRegionBorder(region21, sheet);
            }
            if (i == 19 || i == 20 || i == 21) {
                Cell cell20 = nineteenRow.createCell(2);
                cell20.setCellStyle(style);

                Cell cell21 = nineteenRow.createCell(3);
                cell21.setCellStyle(style);

                if (i == 19) {
                    cell20.setCellValue("实体店");
                    cell21.setCellValue(String.valueOf(totalOrderStatisticsVO.getStoreConsumeRoll())+"*50% = "+String.valueOf(totalOrderStatisticsVO.getStoreTotal()));
                }
                if (i == 20) {
                    cell20.setCellValue("自营商城");
                    cell21.setCellValue(String.valueOf(totalOrderStatisticsVO.getShopConsumeRoll())+"*30% = "+String.valueOf(totalOrderStatisticsVO.getShopTotal()));
                }
                if (i == 21) {
                    cell20.setCellValue("消费券现金金额");
                    cell21.setCellValue(String.valueOf(totalOrderStatisticsVO.getUseConsumeRoll())+"*50% - "+String.valueOf(totalOrderStatisticsVO.getCash()));
                }

                CellRangeAddress region21 = new CellRangeAddress(i - 1, i - 1, 3, iMaxCol);
                sheet.addMergedRegion(region21);
                setRegionBorder(region21, sheet);
            }
            if (i == 22 || i == 25) {
                Cell cell20 = nineteenRow.createCell(0);
                cell20.setCellStyle(style);
                cell20.setCellValue("说明:");

                if (i == 22) {
                    Cell cell21 = nineteenRow.createCell(1);
                    cell21.setCellStyle(style);
                    cell21.setCellValue("（消费劵前期金额=前日消费劵余额 ）         实体店结算T+1、自营店先付款后发货");
                }
                if (i == 25) {
                    Cell cell21 = nineteenRow.createCell(1);
                    cell21.setCellStyle(style);
                    cell21.setCellValue("按充值时间顺序、充值明细核销");
                }
                CellRangeAddress region = new CellRangeAddress(i - 1, i - 1, 1, iMaxCol);
                sheet.addMergedRegion(region);
                //给合并单元格加边框
                setRegionBorder(region, sheet);
            }
            if (i == 23) {
                Cell cell20 = nineteenRow.createCell(0);
                cell20.setCellStyle(style);
                cell20.setCellValue("提货单核销账户");
                CellRangeAddress region = new CellRangeAddress(22, 23, 0, 1);
                sheet.addMergedRegion(region);
                //给合并单元格加边框
                setRegionBorder(region, sheet);
            }
        }
        ServletOutputStream os = response.getOutputStream();
        OutputStream osOut = response.getOutputStream();
        workbook.write(osOut);
        osOut.flush();
        osOut.close();
        logger.info("11111");
    }

    /**
     * 描述信息  格式化合并单元格
     *
     * @Author yaoruiqi
     * @Date: 2023/12/19 06:58
     */
    private static void setRegionBorder(CellRangeAddress region, Sheet sheet) {
        RegionUtil.setBorderBottom(BorderStyle.THIN, region, sheet);
        RegionUtil.setBorderLeft(BorderStyle.THIN, region, sheet);
        RegionUtil.setBorderRight(BorderStyle.THIN, region, sheet);
        RegionUtil.setBorderTop(BorderStyle.THIN, region, sheet);

    }

}
